<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Compile Time Power of a Runtime Base</title>
<link rel="stylesheet" href="../../math.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../index.html" title="Math Toolkit 4.2.0">
<link rel="up" href="../powers.html" title="Basic Functions">
<link rel="prev" href="hypot.html" title="hypot">
<link rel="next" href="rsqrt.html" title="Reciprocal square root">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="hypot.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../powers.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="rsqrt.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="math_toolkit.powers.ct_pow"></a><a class="link" href="ct_pow.html" title="Compile Time Power of a Runtime Base">Compile Time Power of a Runtime
      Base</a>
</h3></div></div></div>
<p>
        The <code class="computeroutput"><span class="identifier">pow</span></code> function effectively
        computes the compile-time integral power of a run-time base.
      </p>
<h5>
<a name="math_toolkit.powers.ct_pow.h0"></a>
        <span class="phrase"><a name="math_toolkit.powers.ct_pow.synopsis"></a></span><a class="link" href="ct_pow.html#math_toolkit.powers.ct_pow.synopsis">Synopsis</a>
      </h5>
<p>
        <a href="../../../../../../boost/math/special_functions/pow.hpp" target="_top"><code class="computeroutput"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">special_functions</span><span class="special">/</span><span class="identifier">pow</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span></code></a>
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">math</span> <span class="special">{</span>

<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">int</span> <span class="identifier">N</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="keyword">constexpr</span> <a class="link" href="../result_type.html" title="Calculation of the Type of the Result"><span class="emphasis"><em>calculated-result-type</em></span></a> <span class="identifier">pow</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">base</span><span class="special">);</span>

<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">int</span> <span class="identifier">N</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Policy</span><span class="special">&gt;</span>
<span class="keyword">constexpr</span> <a class="link" href="../result_type.html" title="Calculation of the Type of the Result"><span class="emphasis"><em>calculated-result-type</em></span></a> <span class="identifier">pow</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">base</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">Policy</span><span class="special">&amp;</span> <span class="identifier">policy</span><span class="special">);</span>

<span class="special">}}</span>
</pre>
<h5>
<a name="math_toolkit.powers.ct_pow.h1"></a>
        <span class="phrase"><a name="math_toolkit.powers.ct_pow.rationale_and_usage"></a></span><a class="link" href="ct_pow.html#math_toolkit.powers.ct_pow.rationale_and_usage">Rationale
        and Usage</a>
      </h5>
<p>
        Computing the power of a number with an exponent that is known at compile
        time is a common need for programmers. In such cases, the usual method is
        to avoid the overhead implied by the <code class="computeroutput"><span class="identifier">pow</span></code>,
        <code class="computeroutput"><span class="identifier">powf</span></code> and <code class="computeroutput"><span class="identifier">powl</span></code>
        C functions by hardcoding an expression such as:
      </p>
<pre class="programlisting"><span class="comment">// Hand-written 8th power of a 'base' variable</span>
<span class="keyword">double</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">base</span><span class="special">*</span><span class="identifier">base</span><span class="special">*</span><span class="identifier">base</span><span class="special">*</span><span class="identifier">base</span><span class="special">*</span><span class="identifier">base</span><span class="special">*</span><span class="identifier">base</span><span class="special">*</span><span class="identifier">base</span><span class="special">*</span><span class="identifier">base</span><span class="special">;</span>
</pre>
<p>
        However, this kind of expression is not really readable (knowing the value
        of the exponent involves counting the number of occurrences of <span class="emphasis"><em>base</em></span>),
        error-prone (it's easy to forget an occurrence), syntactically bulky, and
        non-optimal in terms of performance.
      </p>
<p>
        The <code class="computeroutput"><span class="identifier">pow</span></code> function of Boost.Math
        helps writing this kind expression along with solving all the problems listed
        above:
      </p>
<pre class="programlisting"><span class="comment">// 8th power of a 'base' variable using math::pow</span>
<span class="keyword">double</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">pow</span><span class="special">&lt;</span><span class="number">8</span><span class="special">&gt;(</span><span class="identifier">base</span><span class="special">);</span>
</pre>
<p>
        The expression is now shorter, easier to read, safer, and even faster. Indeed,
        <code class="computeroutput"><span class="identifier">pow</span></code> will compute the expression
        such that only log2(N) products are made for a power of N. For instance in
        the example above, the resulting expression will be the same as if we had
        written this, with only one computation of each identical subexpression:
      </p>
<pre class="programlisting"><span class="comment">// Internal effect of pow&lt;8&gt;(base)</span>
<span class="keyword">double</span> <span class="identifier">result</span> <span class="special">=</span> <span class="special">((</span><span class="identifier">base</span><span class="special">*</span><span class="identifier">base</span><span class="special">)*(</span><span class="identifier">base</span><span class="special">*</span><span class="identifier">base</span><span class="special">))*((</span><span class="identifier">base</span><span class="special">*</span><span class="identifier">base</span><span class="special">)*(</span><span class="identifier">base</span><span class="special">*</span><span class="identifier">base</span><span class="special">));</span>
</pre>
<p>
        Only 3 different products were actually computed.
      </p>
<h5>
<a name="math_toolkit.powers.ct_pow.h2"></a>
        <span class="phrase"><a name="math_toolkit.powers.ct_pow.return_type"></a></span><a class="link" href="ct_pow.html#math_toolkit.powers.ct_pow.return_type">Return
        Type</a>
      </h5>
<p>
        The return type of these functions is computed using the <a class="link" href="../result_type.html" title="Calculation of the Type of the Result"><span class="emphasis"><em>result
        type calculation rules</em></span></a>. For example:
      </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
            If T is a <code class="computeroutput"><span class="keyword">float</span></code>, the return
            type is a <code class="computeroutput"><span class="keyword">float</span></code>.
          </li>
<li class="listitem">
            If T is a <code class="computeroutput"><span class="keyword">long</span> <span class="keyword">double</span></code>,
            the return type is a <code class="computeroutput"><span class="keyword">long</span> <span class="keyword">double</span></code>.
          </li>
<li class="listitem">
            Otherwise, the return type is a <code class="computeroutput"><span class="keyword">double</span></code>.
          </li>
</ul></div>
<h5>
<a name="math_toolkit.powers.ct_pow.h3"></a>
        <span class="phrase"><a name="math_toolkit.powers.ct_pow.constexpr"></a></span><a class="link" href="ct_pow.html#math_toolkit.powers.ct_pow.constexpr">constexpr</a>
      </h5>
<p>
        This function is usable in <code class="computeroutput"><span class="keyword">constexpr</span></code>
        contexts from C++14 onwards.
      </p>
<h5>
<a name="math_toolkit.powers.ct_pow.h4"></a>
        <span class="phrase"><a name="math_toolkit.powers.ct_pow.policies"></a></span><a class="link" href="ct_pow.html#math_toolkit.powers.ct_pow.policies">Policies</a>
      </h5>
<p>
        The final <a class="link" href="../../policy.html" title="Chapter 22. Policies: Controlling Precision, Error Handling etc">Policy</a> argument is optional and can
        be used to control the behaviour of the function: how it handles errors,
        what level of precision to use etc. Refer to the <a class="link" href="../../policy.html" title="Chapter 22. Policies: Controlling Precision, Error Handling etc">policy
        documentation for more details</a>.
      </p>
<h5>
<a name="math_toolkit.powers.ct_pow.h5"></a>
        <span class="phrase"><a name="math_toolkit.powers.ct_pow.error_handling"></a></span><a class="link" href="ct_pow.html#math_toolkit.powers.ct_pow.error_handling">Error
        Handling</a>
      </h5>
<p>
        Two cases of errors can occur when using <code class="computeroutput"><span class="identifier">pow</span></code>:
      </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
            In case of null base and negative exponent, an <a class="link" href="../error_handling.html#math_toolkit.error_handling.overflow_error">overflow_error</a>
            occurs since this operation is a division by 0 (it equals to 1/0).
          </li>
<li class="listitem">
            In case of null base and null exponent, an <a class="link" href="../error_handling.html#math_toolkit.error_handling.indeterminate_result_error">indeterminate_result_error</a>
            occurs since the result of this operation is indeterminate. Those errors
            follow the <a class="link" href="../error_handling.html" title="Error Handling">general policies
            of error handling in Boost.Math</a>.
          </li>
</ul></div>
<p>
        The default overflow error policy is <code class="computeroutput"><span class="identifier">throw_on_error</span></code>.
        A call like <code class="computeroutput"><span class="identifier">pow</span><span class="special">&lt;-</span><span class="number">2</span><span class="special">&gt;(</span><span class="number">0</span><span class="special">)</span></code> will thus throw a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">overflow_error</span></code>
        exception. As shown in the link given above, other error handling policies
        can be used:
      </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
            <code class="computeroutput"><span class="identifier">errno_on_error</span></code>: Sets
            <code class="computeroutput"><span class="special">::</span><span class="identifier">errno</span></code>
            to <code class="computeroutput"><span class="identifier">ERANGE</span></code> and returns
            <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">infinity</span><span class="special">()</span></code>.
          </li>
<li class="listitem">
            <code class="computeroutput"><span class="identifier">ignore_error</span></code>: Returns
            <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">infinity</span><span class="special">()</span></code>.
          </li>
<li class="listitem">
            <code class="computeroutput"><span class="identifier">user_error</span></code>: Returns the
            result of <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">policies</span><span class="special">::</span><span class="identifier">user_overflow_error</span></code>: this function
            must be defined by the user.
          </li>
</ul></div>
<p>
        The default indeterminate result error policy is <code class="computeroutput"><span class="identifier">ignore_error</span></code>,
        which for this function returns 1 since it's the most commonly chosen result
        for a power of 0. Here again, other error handling policies can be used:
      </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
            <code class="computeroutput"><span class="identifier">throw_on_error</span></code>: Throws
            <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">domain_error</span></code>
          </li>
<li class="listitem">
            <code class="computeroutput"><span class="identifier">errno_on_error</span></code>: Sets
            <code class="computeroutput"><span class="special">::</span><span class="identifier">errno</span></code>
            to <code class="computeroutput"><span class="identifier">EDOM</span></code> and returns 1.
          </li>
<li class="listitem">
            <code class="computeroutput"><span class="identifier">user_error</span></code>: Returns the
            result of <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">policies</span><span class="special">::</span><span class="identifier">user_indeterminate_result_error</span></code>: this
            function must be defined by the user.
          </li>
</ul></div>
<p>
        Here is an example of error handling customization where we want to specify
        the result that has to be returned in case of error. We will thus use the
        <code class="computeroutput"><span class="identifier">user_error</span></code> policy, by passing
        as second argument an instance of an overflow_error policy templated with
        <code class="computeroutput"><span class="identifier">user_error</span></code>:
      </p>
<pre class="programlisting"><span class="comment">// First we open the boost::math::policies namespace and define the `user_overflow_error`</span>
<span class="comment">// by making it return the value we want in case of error (-1 here)</span>

<span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">math</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">policies</span> <span class="special">{</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="identifier">T</span> <span class="identifier">user_overflow_error</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*,</span> <span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;)</span>
<span class="special">{</span> <span class="keyword">return</span> <span class="special">-</span><span class="number">1</span><span class="special">;</span> <span class="special">}</span>
<span class="special">}}}</span>


<span class="comment">// Then we invoke pow and indicate that we want to use the user_error policy</span>
<span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">policies</span><span class="special">;</span>
<span class="keyword">double</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">pow</span><span class="special">&lt;-</span><span class="number">5</span><span class="special">&gt;(</span><span class="identifier">base</span><span class="special">,</span> <span class="identifier">policy</span><span class="special">&lt;</span><span class="identifier">overflow_error</span><span class="special">&lt;</span><span class="identifier">user_error</span><span class="special">&gt;</span> <span class="special">&gt;());</span>

<span class="comment">// We can now test the returned value and treat the special case if needed:</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">result</span> <span class="special">==</span> <span class="special">-</span><span class="number">1</span><span class="special">)</span>
<span class="special">{</span>
    <span class="comment">// there was an error, do something...</span>
<span class="special">}</span>
</pre>
<p>
        Another way is to redefine the default <code class="computeroutput"><span class="identifier">overflow_error</span></code>
        policy by using the BOOST_MATH_OVERFLOW_ERROR_POLICY macro. Once the <code class="computeroutput"><span class="identifier">user_overflow_error</span></code> function is defined
        as above, we can achieve the same result like this:
      </p>
<pre class="programlisting"><span class="comment">// Redefine the default error_overflow policy</span>
<span class="preprocessor">#define</span> <span class="identifier">BOOST_MATH_OVERFLOW_ERROR_POLICY</span> <span class="identifier">user_error</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">special_functions</span><span class="special">/</span><span class="identifier">pow</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>

<span class="comment">// From this point, passing a policy in argument is no longer needed, a call like this one</span>
<span class="comment">// will return -1 in case of error:</span>

<span class="keyword">double</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">pow</span><span class="special">&lt;-</span><span class="number">5</span><span class="special">&gt;(</span><span class="identifier">base</span><span class="special">);</span>
</pre>
<h5>
<a name="math_toolkit.powers.ct_pow.h6"></a>
        <span class="phrase"><a name="math_toolkit.powers.ct_pow.acknowledgements"></a></span><a class="link" href="ct_pow.html#math_toolkit.powers.ct_pow.acknowledgements">Acknowledgements</a>
      </h5>
<p>
        Bruno Lalande submitted this addition to Boost.Math.
      </p>
<p>
        Thanks to Joaquín López Muñoz and Scott McMurray for their help in
improving the implementation.
      </p>
<h5>
<a name="math_toolkit.powers.ct_pow.h7"></a>
        <span class="phrase"><a name="math_toolkit.powers.ct_pow.references"></a></span><a class="link" href="ct_pow.html#math_toolkit.powers.ct_pow.references">References</a>
      </h5>
<p>
        D.E. Knuth, <span class="emphasis"><em>The Art of Computer Programming, Vol. 2: Seminumerical
        Algorithms</em></span>, 2nd ed., Addison-Wesley, Reading, MA, 1981
      </p>
</div>
<div class="copyright-footer">Copyright © 2006-2021 Nikhar Agrawal, Anton Bikineev, Matthew Borland,
      Paul A. Bristow, Marco Guazzone, Christopher Kormanyos, Hubert Holin, Bruno
      Lalande, John Maddock, Evan Miller, Jeremy Murphy, Matthew Pulver, Johan Råde,
      Gautam Sewani, Benjamin Sobotta, Nicholas Thompson, Thijs van den Berg, Daryle
      Walker and Xiaogang Zhang<p>
        Distributed under the Boost Software License, Version 1.0. (See accompanying
        file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
      </p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="hypot.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../powers.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="rsqrt.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>
